/**
 * Copyright &copy; 2016-2017 <a href="http://git.oschina.net/whoamien/backend_management">Backend Management</a> All rights reserved.
 */
package com.xw.framework.base.controller;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.SimpleDateFormat;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.beans.propertyeditors.CustomNumberEditor;
import org.springframework.data.domain.Page;
import org.springframework.ui.ModelMap;
import org.springframework.util.Assert;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.xw.framework.base.page.BaseQuery;
import com.xw.framework.base.web.SqlDateEditor;
import com.xw.framework.base.web.SqlTimeEditor;
import com.xw.framework.base.web.TimestampEditor;
import com.xw.framework.vo.UserSessionInfo;
import com.xw.util.AppConstant;
import com.xw.util.BeanUtils;


/**
 * The Class BaseSpringController.
 *
 * @author Xi Wei
 */
public class BaseSpringController {
	
	/** The Constant CREATED_SUCCESS. */
	protected final static String CREATED_SUCCESS = "message.create.success";
	
	/** The Constant UPDATE_SUCCESS. */
	protected final static String UPDATE_SUCCESS = "message.update.success";
	
	/** The Constant DELETE_SUCCESS. */
	protected final static String DELETE_SUCCESS = "message.delete.success";
	
	static {
		System.out.println("Register Converter");
		ConvertRegisterHelper.registerConverters();
	}
	
	/**
	 * Inits the binder.
	 *
	 * @param request the request
	 * @param binder the binder
	 */
	@InitBinder
	protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) {
		binder.registerCustomEditor(Short.class, new CustomNumberEditor(Short.class, true));
		binder.registerCustomEditor(Integer.class, new CustomNumberEditor(Integer.class, true));
		binder.registerCustomEditor(Long.class, new CustomNumberEditor(Long.class, true));
		binder.registerCustomEditor(Float.class, new CustomNumberEditor(Float.class, true));
		binder.registerCustomEditor(Double.class, new CustomNumberEditor(Double.class, true));
		binder.registerCustomEditor(BigDecimal.class, new CustomNumberEditor(BigDecimal.class, true));
		binder.registerCustomEditor(BigInteger.class, new CustomNumberEditor(BigInteger.class, true));

		binder.registerCustomEditor(java.sql.Date.class, new SqlDateEditor());
		binder.registerCustomEditor(java.sql.Time.class, new SqlTimeEditor());
		binder.registerCustomEditor(java.sql.Timestamp.class, new TimestampEditor());
		binder.registerCustomEditor(java.util.Date.class,
				new CustomDateEditor(new SimpleDateFormat(AppConstant.DEFAULT_DATE_FORMAT), true));		
		

	}
	
	/**
	 * To model map.
	 *
	 * @param page the page
	 * @param query the query
	 * @return the model map
	 */
	public static ModelMap toModelMap(Page page, BaseQuery query) {
		return toModelMap("", page, query);
	}

	/**
	 * To model map.
	 *
	 * @param tableId the table id
	 * @param page the page
	 * @param query the query
	 * @return the model map
	 */
	public static ModelMap toModelMap(String tableId, Page page, BaseQuery query) {
		ModelMap model = new ModelMap();
		saveIntoModelMap(tableId, page, query, model);
		return model;
	}
	
	/**
	 * Save into model map.
	 *
	 * @param tableId the table id
	 * @param page the page
	 * @param query the query
	 * @param model the model
	 */
	public static void saveIntoModelMap(String tableId, Page page, BaseQuery query, ModelMap model) {
		Assert.notNull(tableId, "tableId must be not null");
		Assert.notNull(page, "page must be not null");

		model.addAttribute(tableId + "page", page);
		model.addAttribute(tableId + "totalRows", page.getTotalElements());
		model.addAttribute(tableId + "pageRequest", query);
		model.addAttribute(tableId + "query", query);
	}
	
	/**
	 * Copy properties.
	 *
	 * @param target the target
	 * @param source the source
	 */
	public static void copyProperties(Object target, Object source) {
		BeanUtils.copyProperties(target, source);
	}
	
	
	/**
	 * Gets the user session info.
	 *
	 * @param session the session
	 * @return the user session info
	 */
	public UserSessionInfo getUserSessionInfo(HttpSession session){
		return (UserSessionInfo)session.getAttribute(UserSessionInfo.USER_SESSION_INFO_KEY);
	}
	
	/**
	 * 添加Flash消息.
	 *
	 * @param redirectAttributes the redirect attributes
	 * @param messages the messages
	 */
	protected void addMessage(RedirectAttributes redirectAttributes, String... messages) {
		StringBuilder sb = new StringBuilder();
		for (String message : messages){
			sb.append(message).append(messages.length>1?"<br/>":"");
		}
		redirectAttributes.addFlashAttribute("message", sb.toString());
	}
	
	/**
	 * 添加消息的message key.
	 *
	 * @param redirectAttributes the redirect attributes
	 * @param messageKey the message key
	 */
	protected void addMessageKey(RedirectAttributes redirectAttributes, String messageKey) {
		redirectAttributes.addFlashAttribute("messageKey", messageKey);
	}
	
	/**
	 * Adds the error.
	 *
	 * @param redirectAttributes the redirect attributes
	 * @param messages the messages
	 */
	protected void addError(RedirectAttributes redirectAttributes, String... messages) {
		StringBuilder sb = new StringBuilder();
		for (String message : messages){
			sb.append(message).append(messages.length>1?"<br/>":"");
		}
		redirectAttributes.addFlashAttribute("error", sb.toString());
	}
	
	/**
	 * Adds the error key.
	 *
	 * @param redirectAttributes the redirect attributes
	 * @param messageKey the message key
	 */
	protected void addErrorKey(RedirectAttributes redirectAttributes, String messageKey) {
		redirectAttributes.addFlashAttribute("errorKey", messageKey);
	}
	
	/**
	 * Adds the success message in session.
	 *
	 * @param request the request
	 * @param create the create
	 */
	protected void addSuccessMessageInSession(HttpServletRequest request,boolean create){
		if(create){
			request.getSession().setAttribute("messageKey", CREATED_SUCCESS);
		}else{
			request.getSession().setAttribute("messageKey", UPDATE_SUCCESS);
		}
	}
	
	/**
	 * Sync message.
	 *
	 * @param request the request
	 * @param map the map
	 */
	public void syncMessage(HttpServletRequest request,ModelMap map){
		if(request.getSession().getAttribute("message") != null){
			map.addAttribute("message", request.getSession().getAttribute("message"));
			request.getSession().removeAttribute("message");
		}
		if(request.getSession().getAttribute("messageKey") != null){
			map.addAttribute("messageKey", request.getSession().getAttribute("messageKey"));
			request.getSession().removeAttribute("messageKey");
		}
		if(request.getSession().getAttribute("error") != null){
			map.addAttribute("error", request.getSession().getAttribute("error"));
			request.getSession().removeAttribute("error");
		}
		if(request.getSession().getAttribute("errorKey") != null){
			map.addAttribute("errorKey", request.getSession().getAttribute("errorKey"));
			request.getSession().removeAttribute("errorKey");
		}
	}
}
